package storage.record;

import storage.file.Block;
import storage.tx.Transaction;
import static storage.file.Page.*;

public class RecordPage {
	public static final int EMPTY = 0, INUSE = 1;

	private Block blk;
	private TableInfo ti;
	private Transaction tx;
	private int slotsize;
	private int currentslot = -1;

	public RecordPage(Block blk, TableInfo ti, Transaction tx) {
		this.blk = blk;
		this.ti = ti;
		this.tx = tx;
		tx.pin(blk);
		slotsize = ti.recordLength() + INT_SIZE;
	}

	public void close() {
		if (blk != null)
			tx.unpin(blk);
		blk = null;
	}

	public boolean next() {
		return searchFor(INUSE);
	}

	public int getInt(String fldname) {
		int positon = fieldpos(fldname);
		return tx.getInt(blk, positon);
	}

	public String getString(String fldname) {
		int position = fieldpos(fldname);
		return tx.getString(blk, position);
	}
	
	public void setInt(String fldname, int val){
		int position = fieldpos(fldname);
		tx.setInt(blk, position, val);
	}

	public void setString(String fldname, String val){
		int positon = fieldpos(fldname);
		tx.setString(blk, positon, val);
	}
	
	public void delete(){
		int position = currentpos();
		tx.setInt(blk, position, EMPTY);
	}
	
	public boolean insert(){
		currentslot = -1;
		boolean found = searchFor(EMPTY);
		if (found){
			int position = currentpos();
			tx.setInt(blk, position, INUSE);
		}
		return found;
	}
	
	public void moveToID(int id){
		currentslot = id;
	}
	
	public int currentID(){
		return currentslot;
	}
	
	private int currentpos(){
		return currentslot * slotsize;
	}
	
	private int fieldpos(String fldname){
		int offset = INT_SIZE + ti.offset(fldname);
		return currentpos() + offset;
	}
	
	private boolean isValidSlot(){
		return currentpos() + slotsize <=BLOCK_SIZE;
	}
	
	private boolean searchFor(int flag){
		currentslot++;
		while(isValidSlot()){
			int position = currentpos();
			if(tx.getInt(blk, position) == flag)
				return true;
			currentslot++;
		}
		return false;
	}
}
